﻿using Microsoft.Practices.Unity;
using Business.dao.conf;
using Business.dao.utils;
using Business.dao.impl;
using Commons.log;
using Microsoft.Practices.Unity.InterceptionExtension;
using System;

namespace Business.dao.conf
{





    public class BusinessContainer
    {
        private static readonly ILog log = CommonLog.GetLogger();
        private static IUnityContainer _container = null;

        private static IUnityContainer GetContainer()
        {
            if (_container == null)
            {
                CustomAttributeMatchingRule matchingRule = new CustomAttributeMatchingRule(typeof(PerfilSegurancaRequerido), true);


                _container = new UnityContainer()
                        .AddNewExtension<Interception>()
                        .RegisterType<ContextoDB, ContextoDB>(new PerThreadLifetimeManager())
                        .RegisterType<IClassificadorDAO, ClassificadorDAOImpl>()
                        .RegisterType<IQuestaoDAO, QuestaoDAOImpl>()
                        .RegisterInstance<ICallHandler>("MyHandler", new MyHandler())
                        ;

                _container.Configure<Interception>()
                            .SetInterceptorFor<QuestaoDAOImpl>(new VirtualMethodInterceptor())
                            .AddPolicy("Policy1")
                            .AddMatchingRule(matchingRule) // pointcut
                            .AddCallHandler("MyHandler")   // advice
                            ;
            }
            return _container;
        }

        public static T Get<T>()
        {
            return (T)GetContainer().Resolve<T>();
        }

    }


    public class MyHandler : ICallHandler
    {
        public int Order { get; set; }


        static ILog log = CommonLog.GetLogger();

        public IMethodReturn Invoke(IMethodInvocation input,
                             GetNextHandlerDelegate getNext)
        {
            // Declare any variables required for values used in this method here.


            // Perform any pre-processing tasks required in the custom handler here.
            // This code executes before control passes to the next handler.

            log.Info(string.Format("Classe.metodo = {0}", input.MethodBase.ReflectedType.FullName));
            // Use the following line of code in any handler to invoke the next 
            // handler that Unity should execute. This code gets
            // the current return message that you must pass back to the caller:
            IMethodReturn msg = getNext()(input, getNext);

            // Perform any post-processing tasks required in the custom handler here.
            // This code executes after the invocation of the target object method or
            // property accessor, and before control passes back to the previous
            // handler as the Invoke call stack unwinds. You can modify the return 
            // message if required.
            // ...
            // ...

            // Return the message to the calling code, which may be the previous 
            // handler or, if this is the first handler in the chain, the client.   
            return msg;
        }


    }


    [System.AttributeUsage(System.AttributeTargets.Class |
                       System.AttributeTargets.Method,
                       AllowMultiple = true)
    ]
    public class PerfilSegurancaRequerido : System.Attribute
    {
    }




}

